/*
 * @Author: Kiro AI Assistant
 * @Date: 2025-01-10
 * @Description: 性能监控工具 - 用于跟踪和分析应用性能
 */

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// 性能监控工具
/// 提供组件重建跟踪、页面转换监控、内存使用监控等功能
class PerformanceMonitor {
  static final Map<String, int> _rebuildCounts = {};
  static final Map<String, DateTime> _lastRebuildTimes = {};
  static final Map<String, List<Duration>> _rebuildIntervals = {};
  static final Map<String, DateTime> _pageTransitionTimes = {};

  /// 跟踪组件重建
  /// [widgetName] 组件名称
  /// [context] 构建上下文（可选，用于获取更多信息）
  static void trackRebuild(String widgetName, [BuildContext? context]) {
    if (!kDebugMode) return;

    final now = DateTime.now();

    // 更新重建次数
    _rebuildCounts[widgetName] = (_rebuildCounts[widgetName] ?? 0) + 1;

    // 计算重建间隔
    if (_lastRebuildTimes.containsKey(widgetName)) {
      final interval = now.difference(_lastRebuildTimes[widgetName]!);
      _rebuildIntervals.putIfAbsent(widgetName, () => []).add(interval);

      // 只保留最近的10次间隔记录
      if (_rebuildIntervals[widgetName]!.length > 10) {
        _rebuildIntervals[widgetName]!.removeAt(0);
      }
    }

    _lastRebuildTimes[widgetName] = now;

    // 输出重建信息
    final count = _rebuildCounts[widgetName]!;
    final timeStr = now.toString().substring(11, 23); // 只显示时分秒毫秒

    debugPrint('🔄 [Rebuild] $widgetName (#$count) at $timeStr');

    // 如果重建过于频繁，发出警告
    if (_rebuildIntervals[widgetName] != null &&
        _rebuildIntervals[widgetName]!.length >= 3) {
      final recentIntervals = _rebuildIntervals[widgetName]!.take(3).toList();
      final avgInterval =
          recentIntervals.map((d) => d.inMilliseconds).reduce((a, b) => a + b) /
              recentIntervals.length;

      if (avgInterval < 100) {
        // 平均间隔小于100ms
        debugPrint(
            '⚠️  [Performance Warning] $widgetName 重建过于频繁 (平均间隔: ${avgInterval.toStringAsFixed(1)}ms)');
      }
    }
  }

  /// 跟踪页面转换
  /// [fromPage] 源页面名称
  /// [toPage] 目标页面名称
  static void trackPageTransition(String fromPage, String toPage) {
    if (!kDebugMode) return;

    final now = DateTime.now();
    final transitionKey = '$fromPage -> $toPage';

    // 计算页面转换耗时
    if (_pageTransitionTimes.containsKey(fromPage)) {
      final duration = now.difference(_pageTransitionTimes[fromPage]!);
      debugPrint(
          '📱 [Page Transition] $transitionKey (耗时: ${duration.inMilliseconds}ms)');
    } else {
      debugPrint('📱 [Page Transition] $transitionKey');
    }

    _pageTransitionTimes[toPage] = now;
  }

  /// 跟踪网络请求性能
  /// [url] 请求URL
  /// [method] 请求方法
  /// [duration] 请求耗时
  /// [success] 是否成功
  static void trackNetworkRequest(
    String url,
    String method,
    Duration duration,
    bool success,
  ) {
    if (!kDebugMode) return;

    final statusIcon = success ? '✅' : '❌';
    final durationMs = duration.inMilliseconds;

    debugPrint('🌐 [Network] $statusIcon $method $url (${durationMs}ms)');

    // 如果请求耗时过长，发出警告
    if (durationMs > 3000) {
      debugPrint('⚠️  [Performance Warning] 网络请求耗时过长: ${durationMs}ms');
    }
  }

  /// 跟踪音频播放性能
  /// [action] 操作类型（play, pause, seek等）
  /// [duration] 操作耗时
  /// [trackTitle] 音乐标题（可选）
  static void trackAudioPerformance(String action, Duration duration,
      [String? trackTitle]) {
    if (!kDebugMode) return;

    final durationMs = duration.inMilliseconds;
    final trackInfo = trackTitle != null ? ' ($trackTitle)' : '';

    debugPrint('🎵 [Audio] $action${trackInfo} (${durationMs}ms)');

    // 如果音频操作耗时过长，发出警告
    if (durationMs > 1000) {
      debugPrint('⚠️  [Performance Warning] 音频操作耗时过长: ${durationMs}ms');
    }
  }

  /// 跟踪图片加载性能
  /// [imageUrl] 图片URL
  /// [duration] 加载耗时
  /// [success] 是否成功
  /// [fromCache] 是否来自缓存
  static void trackImageLoading(
    String imageUrl,
    Duration duration,
    bool success,
    bool fromCache,
  ) {
    if (!kDebugMode) return;

    final statusIcon = success ? '✅' : '❌';
    final cacheIcon = fromCache ? '💾' : '🌐';
    final durationMs = duration.inMilliseconds;
    final shortUrl =
        imageUrl.length > 50 ? '${imageUrl.substring(0, 47)}...' : imageUrl;

    debugPrint(
        '🖼️  [Image] $statusIcon $cacheIcon $shortUrl (${durationMs}ms)');

    // 如果图片加载耗时过长且不是来自缓存，发出警告
    if (!fromCache && durationMs > 2000) {
      debugPrint('⚠️  [Performance Warning] 图片加载耗时过长: ${durationMs}ms');
    }
  }

  /// 跟踪列表滚动性能
  /// [listName] 列表名称
  /// [itemCount] 列表项数量
  /// [visibleItemCount] 可见项数量
  static void trackListScrolling(
    String listName,
    int itemCount,
    int visibleItemCount,
  ) {
    if (!kDebugMode) return;

    debugPrint(
        '📜 [List Scroll] $listName (总数: $itemCount, 可见: $visibleItemCount)');

    // 如果列表项过多，建议优化
    if (itemCount > 1000) {
      debugPrint('💡 [Performance Tip] $listName 项目过多，建议实现虚拟滚动或分页加载');
    }
  }

  /// 获取重建统计信息
  static Map<String, int> getRebuildStats() {
    return Map.from(_rebuildCounts);
  }

  /// 获取平均重建间隔
  static Map<String, double> getAverageRebuildIntervals() {
    final result = <String, double>{};

    _rebuildIntervals.forEach((widgetName, intervals) {
      if (intervals.isNotEmpty) {
        final avgMs =
            intervals.map((d) => d.inMilliseconds).reduce((a, b) => a + b) /
                intervals.length;
        result[widgetName] = avgMs;
      }
    });

    return result;
  }

  /// 打印性能报告
  static void printPerformanceReport() {
    if (!kDebugMode) return;

    debugPrint('\n📊 ===== 性能监控报告 =====');

    // 重建统计
    if (_rebuildCounts.isNotEmpty) {
      debugPrint('\n🔄 组件重建统计:');
      final sortedRebuilds = _rebuildCounts.entries.toList()
        ..sort((a, b) => b.value.compareTo(a.value));

      for (final entry in sortedRebuilds.take(10)) {
        final avgInterval = _rebuildIntervals[entry.key] != null
            ? (_rebuildIntervals[entry.key]!
                    .map((d) => d.inMilliseconds)
                    .reduce((a, b) => a + b) /
                _rebuildIntervals[entry.key]!.length)
            : 0.0;

        debugPrint(
            '  ${entry.key}: ${entry.value}次 (平均间隔: ${avgInterval.toStringAsFixed(1)}ms)');
      }
    }

    debugPrint('\n📊 ========================\n');
  }

  /// 清除所有统计数据
  static void clearStats() {
    _rebuildCounts.clear();
    _lastRebuildTimes.clear();
    _rebuildIntervals.clear();
    _pageTransitionTimes.clear();

    if (kDebugMode) {
      debugPrint('🧹 [Performance Monitor] 统计数据已清除');
    }
  }

  /// 开始监控会话
  static void startMonitoringSession(String sessionName) {
    if (!kDebugMode) return;

    clearStats();
    debugPrint('🚀 [Performance Monitor] 开始监控会话: $sessionName');
  }

  /// 结束监控会话
  static void endMonitoringSession(String sessionName) {
    if (!kDebugMode) return;

    debugPrint('🏁 [Performance Monitor] 结束监控会话: $sessionName');
    printPerformanceReport();
  }
}

/// 性能监控混入
/// 可以被 StatefulWidget 使用来自动跟踪重建
mixin PerformanceTrackingMixin<T extends StatefulWidget> on State<T> {
  @override
  Widget build(BuildContext context) {
    PerformanceMonitor.trackRebuild(widget.runtimeType.toString(), context);
    return buildWithTracking(context);
  }

  /// 子类需要实现这个方法而不是 build 方法
  Widget buildWithTracking(BuildContext context);
}

/// 性能监控装饰器
/// 用于包装任何 Widget 来跟踪其重建
class PerformanceTracker extends StatelessWidget {
  final Widget child;
  final String name;

  const PerformanceTracker({
    super.key,
    required this.child,
    required this.name,
  });

  @override
  Widget build(BuildContext context) {
    PerformanceMonitor.trackRebuild(name, context);
    return child;
  }
}

/// 网络请求性能监控装饰器
class NetworkPerformanceTracker {
  static Future<T> track<T>(
    String url,
    String method,
    Future<T> Function() request,
  ) async {
    final stopwatch = Stopwatch()..start();
    bool success = false;

    try {
      final result = await request();
      success = true;
      return result;
    } catch (e) {
      success = false;
      rethrow;
    } finally {
      stopwatch.stop();
      PerformanceMonitor.trackNetworkRequest(
        url,
        method,
        stopwatch.elapsed,
        success,
      );
    }
  }
}

/// 音频性能监控装饰器
class AudioPerformanceTracker {
  static Future<T> track<T>(
    String action,
    Future<T> Function() operation, [
    String? trackTitle,
  ]) async {
    final stopwatch = Stopwatch()..start();

    try {
      final result = await operation();
      return result;
    } finally {
      stopwatch.stop();
      PerformanceMonitor.trackAudioPerformance(
        action,
        stopwatch.elapsed,
        trackTitle,
      );
    }
  }
}
